import { DEV } from 'cc/env';

// 精确度默认保留8位小数点
let DotLen = 8;
let Scale = Math.pow(10, DotLen);
let Scale_L = Math.pow(10, DotLen - 1);

type DecimalSign = 1 | -1;
type IntNumber = number;

function decimalStr(str: string) {
  const strLen = str.length;
  if (strLen === DotLen) {
    return str;
  } else if (strLen > DotLen) {
    return str.slice(0, DotLen);
  } else {
    return str + '0'.repeat(DotLen - strLen);
  }
}

// 获取商数和余数
function getShangYu(up: IntNumber, down: IntNumber): { shang: IntNumber; yu: IntNumber } {
  if (up < down) {
    return { shang: 0, yu: up };
  }
  if (up === down) {
    return { shang: 1, yu: 0 };
  }
  let shang = Math.floor(up / down) - 1;
  up = up - down * shang;
  while (up >= down) {
    shang += 1;
    up -= down;
  }
  return { shang: shang, yu: up };
}

// 计算阶乘
// function factorial(n: IntNumber) {
//     if (n <= 1) {
//         return Decimal.one;
//     } else {
//         let result = 1;
//         for (let i = 2; i <= n; i++) {
//             result *= i;
//         }
//         return Decimal.createInt(result);
//     }
// }

/**
 * 定点数计算
 */
export class Decimal {
  static copy(other: Decimal) {
    return new Decimal().copy(other);
  }

  static createInt(value: IntNumber) {
    return new Decimal().setInt(value);
  }

  static createFloat(value: string) {
    return new Decimal().setFloat(value);
  }

  static create(sign: DecimalSign, v1: IntNumber, v2: IntNumber) {
    return new Decimal().set(sign, v1, v2);
  }

  /**
   * 精确度保留n位小数点, 默认是8。
   * @description 注意整数与小数部分长度和不要超过16位，并且整数位大小不要超过「9 * Math.pow(10, 15-n)」，否则运算过程中会出现大整数导致的精度丢失。
   */
  static set accuracy(value: IntNumber) {
    DotLen = Math.max(Math.floor(value), 1);
    Scale = Math.pow(10, DotLen);
    Scale_L = Math.pow(10, DotLen - 1);
    PI_Decimal.setFloat('3.141592653589793');
    PI_HALF_Decimal.setFloat('1.5707963267948966');
    Deg_Rad_Decimal.setFloat('0.017453292519943');
    Rad_Deg_Decimal.setFloat('57.29577951308232');
  }
  static get accuracy() {
    return DotLen;
  }

  /**
   * 180度对应的弧度值 （不要修改此值）
   */
  static get PI() {
    return PI_Decimal;
  }

  /**
   * 180度的一半(90度)对应的弧度值 （不要修改此值）
   */
  static get PI_HALF() {
    return PI_HALF_Decimal;
  }

  /**
   * 1度对应的弧度值 （不要修改此值）
   */
  static get DEG_TO_RAD() {
    return Deg_Rad_Decimal;
  }

  /**
   * 1弧度对应的角度值 （不要修改此值）
   */
  static get RAD_TO_DEG() {
    return Rad_Deg_Decimal;
  }

  /**
   * 0
   */
  static get zero() {
    return new Decimal();
  }

  /**
   * 0 （不要修改此值）
   */
  static get ZERO() {
    Zero_Decimal.sign = 1;
    Zero_Decimal.v1 = 0;
    Zero_Decimal.v2 = 0;
    return Zero_Decimal;
  }

  /**
   * 1
   */
  static get one() {
    return Decimal.createInt(1);
  }

  /**
   * 1 （不要修改此值）
   */
  static get ONE() {
    One_Decimal.sign = 1;
    One_Decimal.v1 = 1;
    One_Decimal.v2 = 0;
    return One_Decimal;
  }

  /**
   * 2
   */
  static get two() {
    return Decimal.createInt(2);
  }

  /**
   * 2 （不要修改此值）
   */
  static get TWO() {
    Two_Decimal.sign = 1;
    Two_Decimal.v1 = 2;
    Two_Decimal.v2 = 0;
    return Two_Decimal;
  }

  /**
   * -1
   */
  static get minus() {
    return Decimal.createInt(-1);
  }

  /**
   * -1 （不要修改此值）
   */
  static get MINUS() {
    Minus_Decimal.sign = -1;
    Minus_Decimal.v1 = 1;
    Minus_Decimal.v2 = 0;
    return Minus_Decimal;
  }

  /**
   * NaN
   */
  static get NaN() {
    return Decimal.create(1, Number.NaN, Number.NaN);
  }

  /**
   * 取较大
   */
  static max(...args: Decimal[]): Decimal {
    let max = args[0];
    for (let index = 1; index < args.length; index++) {
      const num = args[index];
      if (num.GT(max)) {
        max = num;
      }
    }
    return max;
  }

  /**
   * 取较小
   */
  static min(...args: Decimal[]): Decimal {
    let min = args[0];
    for (let index = 1; index < args.length; index++) {
      const num = args[index];
      if (num.LT(min)) {
        min = num;
      }
    }
    return min;
  }

  /**
   * 弧度转角度
   */
  static radiansToDegrees(out: Decimal, radians: Decimal) {
    return out.copy(radians).mul(this.RAD_TO_DEG);
  }

  /**
   * 角度转弧度
   */
  static degreesToRadians(out: Decimal, degrees: Decimal) {
    return out.copy(degrees).mul(this.DEG_TO_RAD);
  }

  /**
   * 正弦函数
   */
  static sin(out: Decimal, angle: Decimal): Decimal {
    // // 预计算阶乘
    // if (Factorial_Decimals.length === 0) {
    //     for (let i = 0, result = 1; i < 21; i++) {
    //         result *= i + 1;
    //         Factorial_Decimals.push(Decimal.createInt(result));
    //     }
    // }

    // // 将角度转换为弧度
    // const radius = TempB1.copy(angle).mod(TempB2.setInt(360)).mul(this.DEG_TO_RAD);

    // // 迭代次数
    // const iterations = 10;// 最大不能超过10，不然会产生超大整数(科学计数法)
    // const result = out.copy(this.ZERO);

    // //  sin(x) = x - x^3/3! + x^5/5! - x^7/7! + ...
    // for (let i = 0; i <= iterations; i++) {
    //     const exponent = 2 * i + 1;
    //     const numerator = TempB2.copy(radius).pow(exponent);
    //     const denominator = Factorial_Decimals[exponent - 1] || factorial(exponent);
    //     const term = numerator.div(denominator).mul((i % 2 === 0) ? this.ONE : this.MINUS);
    //     result.add(term);
    // }

    // return result;
    return this.cos(out, TempB1.copy(angle).addInt(90)).negative();
  }

  /**
   * 余弦函数
   */
  static cos(out: Decimal, angle: Decimal): Decimal {
    // // 预计算阶乘
    // if (Factorial_Decimals.length === 0) {
    //     for (let i = 0, result = 1; i < 21; i++) {
    //         result *= i + 1;
    //         Factorial_Decimals.push(Decimal.createInt(result));
    //     }
    // }

    // // 将角度转换为弧度
    // const radius = TempB1.copy(angle).mod(TempB2.setInt(360)).mul(this.DEG_TO_RAD);

    // // 迭代次数
    // const iterations = 10;// 最大不能超过10，不然会产生超大整数(科学计数法)
    // const result = out.copy(this.ZERO);

    // //  sin(x) = x - x^2/2! + x^4/4! - x^6/6! + ...
    // for (let i = 0; i <= iterations; i++) {
    //     const exponent = 2 * i;
    //     const numerator = TempB2.copy(radius).pow(exponent);
    //     const denominator = Factorial_Decimals[exponent - 1] || factorial(exponent);
    //     const term = numerator.div(denominator).mul((i % 2 === 0) ? this.ONE : this.MINUS);
    //     result.add(term);
    // }

    // return result;

    // 将角度转换为弧度
    const radius = TempB1.copy(angle).modInt(360).mul(this.DEG_TO_RAD);

    // 迭代次数
    const iterations = 9;
    const result = out.copy(this.ONE);

    const term = TempB2.setInt(1);
    for (let i = 1; i <= iterations; i++) {
      term
        .mul(radius)
        .mul(radius)
        .negative()
        .divInt((2 * i - 1) * (2 * i));
      result.add(term);
    }
    return result;
  }

  /**
   * 正切函数
   */
  static tan(out: Decimal, angle: Decimal): Decimal {
    const sinValue = this.sin(out, angle);
    const cosValue = this.cos(TempB3, angle);
    return sinValue.div(cosValue);
  }

  /**
   * 计算反正弦
   */
  static asin(out: Decimal, value: Decimal) {
    // atan(a / Math.sqrt(1 - a * a));
    TempB1.copy(value).pow().negative().add(this.ONE).sqrt();
    TempB2.copy(value).div(TempB1);
    return this.atan(out, TempB2);
  }

  /**
   * 计算反余弦
   */
  static acos(out: Decimal, value: Decimal) {
    if (value.LT(this.MINUS) || value.GT(this.ONE)) {
      return out.set(1, Number.NaN, Number.NaN);
    }
    if (value.EQ(this.ONE)) {
      return out.set(1, 0, 0);
    }
    if (value.EQ(this.ZERO)) {
      return out.set(1, 90, 0);
    }
    if (value.EQ(this.MINUS)) {
      return out.set(1, 180, 0);
    }

    // function modp(a, b) {
    //     return a - Math.floor(a / b) * b;
    // }
    // modp(atan(Math.sqrt(1 - a * a) / a), PI)
    TempB1.copy(value).pow().negative().add(this.ONE).sqrt().div(value);
    this.atan(out, TempB1).modInt(180);
    if (out.isNegative()) {
      return out.addInt(180);
    }
    return out;
  }

  /**
   * 计算反正切
   */
  static atan(out: Decimal, value: Decimal) {
    if (value.EQ(this.ZERO)) {
      return out.copy(this.ZERO);
    }
    if (value.v1 === 1 && value.v2 === 0) {
      return out.set(value.sign, 90, 0);
    }

    let sign = 1;
    let swap = false;
    let correction = false;

    if (out.copy(value).isNegative()) {
      sign = -1;
      out.negative();
    }
    if (out.GT(this.ONE)) {
      out.reciprocal();
      swap = true;
    }
    if (out.GTFloat('0.26794919')) {
      const SQRT3 = TempC1.setFloat('1.7320508075688772'); // √3
      TempC2.copy(out).add(SQRT3);
      out.mul(SQRT3).sub(this.ONE).div(TempC2);
      correction = true;
    }

    TempC1.copy(out)
      .sub(TempC2.setFloat('0.3333333342477778').mul(TempC3.copy(out).pow(3)))
      .add(TempC2.setFloat('0.19999967200053792').mul(TempC3.mul(out).mul(out)))
      .add(TempC2.setFloat('0.11108765927193148').mul(TempC3.mul(out)))
      .sub(TempC2.setFloat('0.14285489799446008').mul(TempC3.mul(out)))
      .sub(TempC2.setFloat('0.0849762066621346').mul(TempC3.mul(out)));
    out.copy(TempC1);

    if (correction) {
      out.addFloat('0.5235987755982988'); // PI / 6
    }
    if (swap) {
      out.sub(this.PI_HALF).negative();
    }

    out.sign *= sign;

    return out.mul(this.RAD_TO_DEG);
  }

  /**
   * 计算反正切，给定 x 和 y 的值
   */
  static atan2(out: Decimal, y: Decimal, x: Decimal) {
    if (x.EQ(this.ZERO) && y.EQ(this.ZERO)) {
      return out.copy(this.ZERO);
    }

    if (x.GT(this.ZERO)) {
      return this.atan(out, TempD1.copy(y).div(x));
    } else if (x.LT(this.ZERO) && y.GE(this.ZERO)) {
      return this.atan(out, TempD1.copy(y).div(x)).addInt(180);
    } else if (x.LT(this.ZERO) && y.LT(this.ZERO)) {
      return this.atan(out, TempD1.copy(y).div(x)).subInt(180);
    } else if (x.EQ(this.ZERO) && y.GT(this.ZERO)) {
      return out.setInt(90);
    } else {
      return out.setInt(-90);
    }
  }

  // 符号位
  private _sign: DecimalSign = 1;
  public get sign(): DecimalSign {
    return this._sign;
  }
  private set sign(value: DecimalSign) {
    this._sign = value;
  }
  // 商
  private _v1: IntNumber = 0;
  public get v1(): IntNumber {
    return this._v1;
  }
  private set v1(value: IntNumber) {
    this._v1 = value;
  }
  // 余
  private _v2: IntNumber = 0;
  public get v2(): IntNumber {
    return this._v2;
  }
  private set v2(value: IntNumber) {
    this._v2 = value;
  }

  /**
   * 用于等号赋值
   * @example
   * const a = new Decimal('1');
   * const b = new Decimal('10');
   * a.value = b;
   */
  public set value(other: Decimal) {
    this.sign = other.sign;
    this.v1 = other.v1;
    this.v2 = other.v2;
  }

  /**
   * 传入字符串数字
   * @param value 字符串数字(不支持科学计数)
   */
  constructor(value: string);
  /**
   * 构造 0
   */
  constructor();
  constructor(value?: string) {
    this.setFloat(value);
  }

  /**
   * 设置, 默认为0
   */
  set(sign: DecimalSign = 1, v1: IntNumber = 0, v2: IntNumber = 0) {
    this.sign = sign;
    this.v1 = v1;
    this.v2 = v2;
    return this;
  }

  /**
   * 通过float字符串设置, 默认为0
   */
  setFloat(value: string = '') {
    if (!value) {
      return this.set();
    }

    // 符号位
    this.sign = value[0] === '-' ? -1 : 1;

    // 分割整数与小数
    const strArr = value.split('.');

    // 整数
    this.v1 = Math.abs(parseInt(strArr[0] || '0'));

    // 小数
    this.v2 = strArr.length === 1 ? 0 : parseInt(decimalStr(strArr[1]));

    if (this.v1 === 0 && this.v2 === 0) {
      this.sign = 1;
    }

    return this;
  }

  /**
   * 通过int设置, 默认为0
   */
  setInt(value: IntNumber = 0) {
    if (DEV) {
      if (value !== Math.floor(value)) {
        console.error('setInt: 参数必须是整数，而不应该是', value);
      }
    }
    if (value < 0) {
      this.sign = -1;
      this.v1 = Math.floor(-value);
      this.v2 = 0;
    } else {
      this.sign = 1;
      this.v1 = Math.floor(value);
      this.v2 = 0;
    }
    return this;
  }

  /**
   * 通过其他Decimal设置
   */
  copy(other: Decimal) {
    this.sign = other.sign;
    this.v1 = other.v1;
    this.v2 = other.v2;
    return this;
  }

  /**
   * 转为浮点数
   * @param strict 严格模式，默认关闭。开启后额外消耗性能，避免定点数转小数时出现精度问题。
   */
  toNumber(strict = false): number {
    if (strict) {
      return parseFloat(this.toString());
    }
    return this.sign * (this.v1 + this.v2 / Scale);
  }

  /**
   * 转为字符串
   */
  toString(): string {
    if (this.sign === 1) {
      return this.v1.toString() + '.' + '0'.repeat(DotLen - this.v2.toString().length) + this.v2;
    }
    return '-' + this.v1.toString() + '.' + '0'.repeat(DotLen - this.v2.toString().length) + this.v2;
  }

  /**
   * 转为大整数
   */
  toBigInt(): IntNumber {
    return this.sign * (this.v1 * Scale + this.v2);
  }

  /**
   * 是否为0
   */
  isZero() {
    return this.v1 === 0 && this.v2 === 0;
  }

  /**
   * 是否是负数
   */
  isNegative() {
    return this.sign < 0 && (this.v1 > 0 || this.v2 > 0);
  }

  /**
   * 是否是NaN
   */
  isNaN() {
    return Number.isNaN(this.v1) || Number.isNaN(this.v2);
  }

  /**
   * 克隆
   */
  clone(): Decimal {
    return new Decimal().copy(this);
  }

  /**
   * 向下取整
   */
  floor() {
    if (this.v2 > 0 && this.sign === -1) {
      this.v1 += 1;
    }
    this.v2 = 0;
    return this;
  }

  /**
   * 向上取整
   */
  ceil() {
    if (this.v2 > 0 && this.sign === 1) {
      this.v1 += 1;
    }
    this.v2 = 0;
    if (this.v1 === 0) {
      this.sign = 1;
    }
    return this;
  }

  /**
   * 四舍五入
   */
  round() {
    if (this.v2 > Scale >> 1) {
      this.v1 += 1;
    }
    this.v2 = 0;
    if (this.v1 === 0) {
      this.sign = 1;
    }
    return this;
  }

  /**
   * 绝对值
   */
  abs(): Decimal {
    this.sign = 1;
    return this;
  }

  /**
   * @deprecated 使用negative代替
   */
  reverse(): Decimal {
    this.sign *= -1;
    return this;
  }

  /**
   * 相反数
   */
  negative(): Decimal {
    this.sign *= -1;
    return this;
  }

  /**
   * 倒数
   */
  reciprocal(): Decimal {
    return this.copy(Decimal.ONE.div(this));
  }

  /**
   * 加法
   * @param other
   */
  add(other: Decimal): Decimal {
    let num = this.toBigInt() + other.toBigInt();
    let sign: DecimalSign = 1;
    if (num < 0) {
      sign = -1;
      num = -num;
    }
    const res = getShangYu(num, Scale);

    this.sign = sign;
    this.v1 = res.shang;
    this.v2 = res.yu;
    return this;
  }

  /**
   * 加法
   * @param other
   */
  addInt(other: IntNumber): Decimal {
    return this.add(Temp.setInt(other));
  }

  /**
   * 加法
   * @param other
   */
  addFloat(other: string): Decimal {
    return this.add(Temp.setFloat(other));
  }

  /**
   * 减法
   * @param other
   */
  sub(other: Decimal): Decimal {
    let num = this.toBigInt() - other.toBigInt();
    let sign: DecimalSign = 1;
    if (num < 0) {
      sign = -1;
      num = -num;
    }
    const res = getShangYu(num, Scale);

    this.sign = sign;
    this.v1 = res.shang;
    this.v2 = res.yu;
    return this;
  }

  /**
   * 减法
   * @param other
   */
  subInt(other: IntNumber): Decimal {
    return this.sub(Temp.setInt(other));
  }

  /**
   * 减法
   * @param other
   */
  subFloat(other: string): Decimal {
    return this.sub(Temp.setFloat(other));
  }

  /**
   * 乘法
   * @param other
   */
  mul(other: Decimal): Decimal {
    const num = this.v1 * other.v1;
    const tmp1 = getShangYu(this.v1 * other.v2, Scale);
    const tmp2 = getShangYu(this.v2 * other.v1, Scale);
    const tmp3 = getShangYu(this.v2 * other.v2, Scale);

    const tmp4 = Temp1.setInt(num).add(Temp2.set(1, tmp1.shang, tmp1.yu)).add(Temp2.set(1, tmp2.shang, tmp2.yu)).add(Temp2.set(1, 0, tmp3.shang));
    const sign: DecimalSign = this.sign === other.sign ? 1 : -1;

    this.sign = sign;
    this.v1 = tmp4.v1;
    this.v2 = tmp4.v2;
    return this;
  }

  /**
   * 乘法
   * @param other
   */
  mulInt(other: IntNumber): Decimal {
    return this.mul(Temp.setInt(other));
  }

  /**
   * 乘法
   * @param other
   */
  mulFloat(other: string): Decimal {
    return this.mul(Temp.setFloat(other));
  }

  /**
   * 除法
   * @param other
   */
  div(other: Decimal): Decimal {
    const down = other.v1 * Scale + other.v2;
    if (down === 0) {
      return this.set(1, Number.NaN, Number.NaN);
    }
    const up = this.v1 * Scale + this.v2;
    const tmp1 = getShangYu(up, down);
    const tmp2 = getShangYu(tmp1.yu * Scale, down);
    const sign: DecimalSign = this.sign === other.sign ? 1 : -1;

    this.sign = sign;
    this.v1 = tmp1.shang;
    this.v2 = tmp2.shang;
    return this;
  }

  /**
   * 除法
   * @param other
   */
  divInt(other: IntNumber): Decimal {
    return this.div(Temp.setInt(other));
  }

  /**
   * 除法
   * @param other
   */
  divFloat(other: string): Decimal {
    return this.div(Temp.setFloat(other));
  }

  /**
   * 取余数
   * @param other
   */
  mod(other: Decimal): Decimal {
    const down = other.v1 * Scale + other.v2;

    // 分母为0
    if (down === 0) {
      return this.set(1, Number.NaN, Number.NaN);
    }
    // 分子 < 分母
    if (this.v1 < other.v1 || (this.v1 === other.v1 && this.v2 < other.v2)) {
      return this;
    }
    // 分子 == 分母
    if (this.v1 === other.v1 && this.v2 === other.v2) {
      return this.set();
    }

    const up = this.v1 * Scale + this.v2;
    const tmp1 = getShangYu(up, down);
    const tmp2 = getShangYu(tmp1.yu, Scale);

    this.v1 = tmp2.shang;
    this.v2 = tmp2.yu;
    return this;
  }

  /**
   * 取余数
   * @param other
   */
  modInt(other: IntNumber): Decimal {
    return this.mod(Temp.setInt(other));
  }

  /**
   * 取余数
   * @param other
   */
  modFloat(other: string): Decimal {
    return this.mod(Temp.setFloat(other));
  }

  /**
   * n次方
   * @param n 整数
   */
  pow(n: IntNumber = 2) {
    if (n === 0) {
      this.sign = 1;
      this.v1 = 1;
      this.v2 = 0;
    } else if (n > 0) {
      const clone = TempA1.copy(this);
      for (let index = 1; index < n; index++) {
        this.mul(clone);
      }
    } else {
      const clone = TempA1.copy(this);
      this.sign = 1;
      this.v1 = 1;
      this.v2 = 0;
      for (let index = -1; index >= n; index--) {
        this.div(clone);
      }
    }

    return this;
  }

  /**
   * 开方
   */
  sqrt() {
    if (this.LE(Zero_Decimal)) {
      return this.set(1, Number.NaN, Number.NaN);
    }
    const decimal = 5 * Scale_L;

    const x0 = TempA2.copy(this).div(TempA1.copy(Decimal.TWO));
    const x1 = TempA3.copy(this).div(TempA1.copy(Decimal.TWO).mul(x0)).add(TempA1.set(1, 0, decimal).mul(x0));

    while (TempA1.copy(x1).sub(x0).abs().GT(Threshold_Decimal)) {
      x0.copy(x1);
      x1.copy(this).div(TempA1.copy(Decimal.TWO).mul(x0)).add(TempA1.set(1, 0, decimal).mul(x0));
    }

    this.sign = x1.sign;
    this.v1 = x1.v1;
    this.v2 = x1.v2;
    return this;
  }

  /**
   * 小于
   * @param other
   */
  LT(other: Decimal): boolean {
    return this.toBigInt() < other.toBigInt();
  }

  /**
   * 小于
   * @param other
   */
  LTInt(other: IntNumber): boolean {
    return this.LT(Temp.setInt(other));
  }

  /**
   * 小于
   * @param other
   */
  LTFloat(other: string): boolean {
    return this.LT(Temp.setFloat(other));
  }

  /**
   * 小于等于
   * @param other
   */
  LE(other: Decimal): boolean {
    return this.toBigInt() <= other.toBigInt();
  }

  /**
   * 小于等于
   * @param other
   */
  LEInt(other: IntNumber): boolean {
    return this.LE(Temp.setInt(other));
  }

  /**
   * 小于等于
   * @param other
   */
  LEFloat(other: string): boolean {
    return this.LE(Temp.setFloat(other));
  }

  /**
   * 等于
   * @param other
   */
  EQ(other: Decimal): boolean {
    return this.toBigInt() === other.toBigInt();
  }

  /**
   * 等于
   * @param other
   */
  EQInt(other: IntNumber): boolean {
    return this.EQ(Temp.setInt(other));
  }

  /**
   * 等于
   * @param other
   */
  EQFloat(other: string): boolean {
    return this.EQ(Temp.setFloat(other));
  }

  /**
   * 不等于
   * @param other
   */
  NE(other: Decimal): boolean {
    return this.toBigInt() !== other.toBigInt();
  }

  /**
   * 不等于
   * @param other
   */
  NEInt(other: IntNumber): boolean {
    return this.NE(Temp.setInt(other));
  }

  /**
   * 不等于
   * @param other
   */
  NEFloat(other: string): boolean {
    return this.NE(Temp.setFloat(other));
  }

  /**
   * 大于
   * @param other
   */
  GT(other: Decimal): boolean {
    return this.toBigInt() > other.toBigInt();
  }

  /**
   * 大于
   * @param other
   */
  GTInt(other: IntNumber): boolean {
    return this.GT(Temp.setInt(other));
  }

  /**
   * 大于
   * @param other
   */
  GTFloat(other: string): boolean {
    return this.GT(Temp.setFloat(other));
  }

  /**
   * 大于等于
   * @param other
   */
  GE(other: Decimal): boolean {
    return this.toBigInt() >= other.toBigInt();
  }

  /**
   * 大于等于
   * @param other
   */
  GEInt(other: IntNumber): boolean {
    return this.GE(Temp.setInt(other));
  }

  /**
   * 大于等于
   * @param other
   */
  GEFloat(other: string): boolean {
    return this.GE(Temp.setFloat(other));
  }
}

// 参数类型转换
const Temp = new Decimal();

// 加减乘除
const Temp1 = new Decimal();
const Temp2 = new Decimal();

// 开方平方
const TempA1 = new Decimal();
const TempA2 = new Decimal();
const TempA3 = new Decimal();

// 三角函数
const TempB1 = new Decimal();
const TempB2 = new Decimal();
const TempB3 = new Decimal();
const TempC1 = new Decimal();
const TempC2 = new Decimal();
const TempC3 = new Decimal();
const TempD1 = new Decimal();

// 阶乘
// const Factorial_Decimals: Decimal[] = [];

// 常量
const Threshold_Decimal = Decimal.create(1, 0, 1);
const Zero_Decimal = Decimal.createInt(0);
const One_Decimal = Decimal.createInt(1);
const Two_Decimal = Decimal.createInt(2);
const Minus_Decimal = Decimal.createInt(-1);
const PI_Decimal = Decimal.createFloat('3.141592653589793'); // PI
const PI_HALF_Decimal = Decimal.createFloat('1.5707963267948966'); // PI / 2
const Deg_Rad_Decimal = Decimal.createFloat('0.017453292519943'); // PI / 180
const Rad_Deg_Decimal = Decimal.createFloat('57.29577951308232'); // 180 / PI
